#ifndef PARSER_H
#define PARSER_H

#include "debugstreams.h"
#include "StatusCode.h"
#include "ElementDOM.h"

#include <map>
#include <stack>

using namespace std;

/**
 * Cette classe est un parseur XML basé sur l'implémentation DOM : on
 * lit le fichier, que l'on convertit en un "arbre", et on crée une
 * map qui lie chaque tag à un ElementDOM. Peut sauter automatiquement les
 * commentaires et headers (version XML). Permet de lire n'importe
 * quel fichier XML (avec ou sans attribut dans les champs de tag).
 *
 * @see ElementDOM
 * @author Johan "Solo" Luisier
 * @date 2009/06/04
 */
class Parser
{
 public:
  Parser();
  Parser(const string& nom_fichier);
  virtual ~Parser();
  void setNomFichier(const string& nom_fichier);
  StatusCode chargerFichier();
  StatusCode lireDocument();
  static void setLevel(const DebugLevelType& lvl, const unsigned int& lequel);
  StatusCode getInformations(map< string, string >& infosLues) const;
  StatusCode getStructureFichier(vector< const ElementDOM* >& structLue) const;
 protected:
  /**
   * Nom du fichier qui sera lu.
   */
  string nomFichier;
  /**
   * Contenu du fichier, sans retour à la ligne.
   */
  string donnees;
  /**
   * Nombre de caractères présent dans donnees.
   */
  unsigned int taille;
  /**
   * Contient l'association balise - ElementDOM. La balise utilisée
   * ici peut être modifiée (ajout de '+') si une balise avec le même
   * nom est déjà présente.
   */
  map< string, ElementDOM > Informations;
  /**
   * Sert à la vérification de la syntaxe XML.
   */
  stack< string > Pile;
  /**
   * Sert à l'identification du parent de chaque ElementDOM. C'est le
   * numero de l'élément qui contient l'élément précédent.
   */
  stack< int > Parents;
  /**
   * Numérote les ElementDOM trouvés : permet ensuite de reconstruire
   * la structure du fichier à partir de Informations (dans un map,
   * l'ordre n'est pas préservé).
   */
  unsigned int numeroElement;
  /**
   * Stocke les pointeurs sur les ElementDOM, afin de pouvoir
   * simplement reconstruire le fichier dans sa structure originale.
   */
  vector< const ElementDOM* > ordre;
  /**
   * Sert à vérifier que les données ont bien été lues.
   */
  bool donneesLues;
 private:
  static DebugLevelType elementaire, /**< Niveau de sortie des
					fonctions basiques */
    fonction; /**< Niveau de sortie des fonctions de haut niveau. */
  /**
   * Position de lecture du fichier .xml. 
   */
  int index;
  StatusCode trouverOuvrante ();
  // Cherche le caractere <, en fonction de la derniere position de lecture
  StatusCode trouverFermante ();
  // Cherche le caractère >, en fonction de la derniere position de lecture (?)
  void sauterBlanc();
  // Avance l'index de lecture jusqu'au moment ou y a plus de blancs
  // (caractere vide)
  void wipeBlank(string& avecEspaces);
  // Enlève les blancs ' ' à la fin d'une string
  StatusCode litBalise();
  // Lit et renvoie le contenu d'une balise
  StatusCode skipComment();
  // Saute les parties commentées <!-- -->
  StatusCode verifierContenuFutur(const string& future);
  // Lit le contenu de la prochaine balise et le compare avec la chaine b
  ElementDOM isolerAttributs(string& balise);

};

#endif // PARSER_H
